package cn.getech.data.development.service.impl;

import cn.getech.data.development.constant.LastRunState;
import cn.getech.data.development.entity.*;
import cn.getech.data.development.mapper.JobRunHistoryLogMapper;
import cn.getech.data.development.mapper.JobRunHistoryMapper;
import cn.getech.data.development.service.JobInfoService;
import cn.getech.data.development.service.JobRunHistoryService;
import cn.getech.data.development.utils.hadoop.HadoopLogUtils;
import cn.getech.data.intelligence.common.utils.PageUtils;
import cn.getech.data.intelligence.common.utils.Query;
import cn.getech.system.center.model.dto.SysUserDto;
import cn.getech.system.center.service.SysUserService;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 任务执行历史表 服务实现类
 * </p>
 *
 * @author zenith
 * @since 2018-08-27
 */
@Service
public class JobRunHistoryServiceImpl extends ServiceImpl<JobRunHistoryMapper, JobRunHistory> implements JobRunHistoryService {
    @Autowired
    private JobRunHistoryMapper jobRunHistoryMapper;
    @Autowired
    private JobInfoService jobInfoService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private JobRunHistoryLogMapper jobRunHistoryLogMapper;

    @Override
    public List<ProcInfo> logProcs(Integer type) {
        //作业流
        List<Integer> jobInfoIds = jobInfoService.selectJobIds();
        if(CollectionUtil.isNotEmpty(jobInfoIds)){
            List<ProcInfo> procInfos = jobRunHistoryMapper.listJobs(jobInfoIds,type);
            if(CollectionUtil.isNotEmpty(procInfos)){
                return procInfos;
            }
        }
        return null;
    }

    @Override
    public List<Long> logUsers(Integer type) {
        //作业流
        List<Integer> jobInfoIds = jobInfoService.selectJobIds();
        if(CollectionUtil.isNotEmpty(jobInfoIds)){
            List<Long> userInfos = jobRunHistoryMapper.logUsers(jobInfoIds,type);
            if(CollectionUtil.isNotEmpty(userInfos)){
                return userInfos;
            }
        }
        return null;
    }

    @Override
    public List<JobRunHistory> selectListRunAndStop(String param) {
        if(!StringUtils.isEmpty(param)){
            List<String> oozieIds = new ArrayList<>(Arrays.asList(param.split(",")));
            return jobRunHistoryMapper.selectListRunAndStop(oozieIds);
        }else{
            return jobRunHistoryMapper.selectListRunAndStop(null);
        }

    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Object proc_id = params.get("proc_id");
        List<Integer> jobInfoIds = null;
        if (ObjectUtils.isEmpty(proc_id)) {
            jobInfoIds = jobInfoService.selectJobIds();
        } else {
            Integer procId = Integer.parseInt(proc_id.toString());
            jobInfoIds = jobInfoService.selectJobIdsByProcId(procId);
        }
        if (CollectionUtil.isNotEmpty(jobInfoIds)) {
            params.put("jobInfoIds",jobInfoIds);
            IPage<JobRunHistory> page = jobRunHistoryMapper.queryPage((Page<JobRunHistory>) new Query<JobRunHistory>().getPage(params), params);
            List<SysUserDto> userList = sysUserService.listAllUsers();
            Map<Long, String> userMap = userList.stream().collect(
                    Collectors.toMap(SysUserDto::getUserId, SysUserDto::getUsername));
            if (CollectionUtil.isNotEmpty(page.getRecords())) {
                for (JobRunHistory record : page.getRecords()) {
                    if (record.getCreatePer() != null) {
                        record.setCreatePerName(userMap.get(record.getCreatePer()));
                    }
                }
            }
            return new PageUtils(page);
        }else{
            return new PageUtils(null,0,0,0);
        }
    }

    @Override
    public List<JobRunHistory> getInfoByJobId(List<Integer> jobIds) {
        return jobRunHistoryMapper.getInfoByJobId(jobIds);
    }

    @Override
    public List<String> selectOozieIdsByDepOozieIds(List<String> depOozieIds) {

        return this.baseMapper.getOozieIdByDepOozieId(depOozieIds);
    }

    @Override
    public boolean saveOrUpdate2(JobRunHistory entity) {
        JobRunHistoryLogEntity logEntity = null;
        if(!StringUtils.isEmpty(entity.getLog())){
            logEntity = new JobRunHistoryLogEntity();
            logEntity.setLog(entity.getLog());
            entity.setLog("");
        }

        if(null != entity && null != entity.getId()){
            JobRunHistory jobRunHistory = getById(entity.getId());
            //判断对象的字段是否超时
            if(null != jobRunHistory && Objects.equals(jobRunHistory.getIsOutHours(),1)){
                entity.setIsOutHours(1);
            }
            //判断是否是停止状态(则不修改)
            if(null != jobRunHistory && Objects.equals(jobRunHistory.getState(), LastRunState.STOP.getCode())){
                entity.setState(LastRunState.STOP.getCode());
            }
        }

        saveOrUpdate(entity);

        if(logEntity != null){
            JobRunHistory jobRunHistory = getOne(new QueryWrapper<JobRunHistory>()
                    .eq("job_info_id",entity.getJobInfoId())
                    .eq("oozie_job_id", entity.getOozieJobId())
            .last(" limit 1 "));
            if(jobRunHistory == null){
                return false;
            }

            logEntity.setId(jobRunHistory.getId());
            JobRunHistoryLogEntity oldLog = jobRunHistoryLogMapper.selectById(logEntity.getId());
            if(oldLog == null)
                jobRunHistoryLogMapper.insert(logEntity);
            else
                jobRunHistoryLogMapper.updateById(logEntity);
        }
        return true;
    }

    @Override
    public String getLog(Integer id) {
        JobRunHistoryLogEntity oldLog = jobRunHistoryLogMapper.selectById(id);
        if(oldLog == null)
            return null;
        else
            return HadoopLogUtils.handleLog(oldLog.getLog());
//            return oldLog.getLog().replaceAll("\r\n", "<br/>").replaceAll("\t", "&nbsp;&nbsp;&nbsp;&nbsp;").replaceAll("\n", "<br/>");
    }

    @Override
    public void removeLogic(JobDepHistory jobDepHistory) {
        jobRunHistoryMapper.removeLogic(jobDepHistory);
    }

    @Override
    public void removeLogicById(Integer id) {
        JobDepHistory jobDepHistory=new JobDepHistory();
        jobDepHistory.setId(id);
        removeLogic(jobDepHistory);
    }

    @Override
    public void moveLog(String endTime) {
        int currPage = 0;
        int limit = 500;
        Map<String,Object> params = new HashMap<>();
        params.put("endTime", endTime);
        params.put("offset", currPage * limit);
        params.put("limit", limit);
        List<Integer> idList = baseMapper.selectIdList(params);
        while (idList != null && idList.size() > 0){
            for(Integer id : idList){
                JobRunHistory jobRunHistory = baseMapper.selectById(id);
                if(jobRunHistory == null){
                    continue;
                }
                if(StringUtils.isEmpty(jobRunHistory.getLog()))
                    continue;

                JobRunHistoryLogEntity logEntity = new JobRunHistoryLogEntity();
                logEntity.setId(jobRunHistory.getId());
                JobRunHistoryLogEntity oldLog = jobRunHistoryLogMapper.selectById(logEntity.getId());
                if(oldLog == null)
                    jobRunHistoryLogMapper.insert(logEntity);
                else
                    jobRunHistoryLogMapper.updateById(logEntity);

                jobRunHistory.setLog("");
                baseMapper.updateById(jobRunHistory);
            }

            currPage++;
            params.put("offset", currPage * limit);
            idList = baseMapper.selectIdList(params);
        }
    }

    @Override
    public List<JobRunHistory> selectAllRunningList() {
        return baseMapper.selectAllRunningList();
    }

    @Override
    public JobRunHistory getById(Serializable id) {
        JobRunHistory jobRunHistory = super.getById(id);
        if (jobRunHistory.getJobInfoId() != null) {
            JobInfo job = jobInfoService.getById(jobRunHistory.getJobInfoId());
            jobRunHistory.setJobName(job.getName());
        }
        return jobRunHistory;
    }
}
